package com.plan.controller.card;

import com.plan.base.constant.BaseCode;
import com.plan.base.constant.Constant;
import com.plan.base.entity.Result;
import com.plan.base.util.DateUtil;
import com.plan.controller.card.request.CompleteAllReq;
import com.plan.controller.card.request.CopyHistoryDayPlanReq;
import com.plan.controller.card.request.DayPlanAddOrUpdateReq;
import com.plan.controller.card.request.DayPlanListReq;
import com.plan.controller.card.response.DayPlanListRes;
import com.plan.controller.card.response.DayPlanMainInfoRes;
import com.plan.controller.user.response.UserVO;
import com.plan.entity.card.DayPlan;
import com.plan.enums.DayPlanStatusEnum;
import com.plan.enums.DelFlagEnum;
import com.plan.service.card.DayPlanService;
import com.plan.service.card.TeamService;
import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;

/**
 * 今日任务
 *
 * @author zcl
 */
@RestController
@RequestMapping("dayPlan/")
public class DayPlanController {
    @Resource
    private TeamService teamService;
    @Resource
    private DayPlanService dayPlanService;

    /**
     * 新建今日任务
     */
    @PostMapping(value = "add")
    public Result<Long> add(@RequestBody DayPlanAddOrUpdateReq req, HttpServletRequest httpRequest) {
        UserVO vo = (UserVO) httpRequest.getAttribute(Constant.USER_KEY);
        Result<Long> check = this.checkParam(req, vo);
        if (!check.isOk()) {
            return check;
        }
        DayPlan plan = new DayPlan();
        BeanUtils.copyProperties(req, plan);
        plan.setCreatorId(vo.getId());
        plan.setUpdaterId(vo.getId());
        plan.setYearMonthDay(DateUtil.getYearMonthDayFromDate(req.getYearMonthDay()));
        plan.setStatus(DayPlanStatusEnum.NEW.getStatus());
        plan.setDelFlag(DelFlagEnum.NORMAL.getType());
        if (plan.getIntoMemory() == null) {
            plan.setIntoMemory(0);
        }
        if (plan.getIntoTaskRepository() == null) {
            plan.setIntoTaskRepository(0);
        }

        return dayPlanService.insert(plan);
    }

    /**
     * 任务开始
     */
    @PostMapping(value = "start")
    public Result<Long> start(Long id, HttpServletRequest httpRequest) {
        UserVO vo = (UserVO) httpRequest.getAttribute(Constant.USER_KEY);
        return dayPlanService.start(id, vo);
    }

    /**
     * 任务完成
     */
    @PostMapping(value = "complete")
    public Result<Long> complete(Long id, HttpServletRequest httpRequest) {
        UserVO vo = (UserVO) httpRequest.getAttribute(Constant.USER_KEY);
        return dayPlanService.complete(id, vo);
    }

    /**
     * 删除今日任务
     */
    @PostMapping(value = "delete")
    public Result<Long> delete(Long id, HttpServletRequest httpRequest) {
        if (id == null) {
            return Result.fail(BaseCode.PARAM_ERROR);
        }
        UserVO vo = (UserVO) httpRequest.getAttribute(Constant.USER_KEY);
        return dayPlanService.delete(id, vo.getId());
    }

    /**
     * 今日计划列表
     */
    @PostMapping(value = "todayList")
    public Result<DayPlanMainInfoRes> todayList(@RequestBody DayPlanListReq req, HttpServletRequest httpRequest) {
        if (req.getTeamId() == null || req.getCardId() == null) {
            return Result.fail(BaseCode.PARAM_ERROR);
        }
        UserVO user = (UserVO) httpRequest.getAttribute(Constant.USER_KEY);
        if (!teamService.isUserInTeam(req.getTeamId(), user.getId())) {
            return Result.fail(BaseCode.ILLEGAL_OPERATION);
        }
        req.setYearMonthDay(DateUtil.getYearMonthDayFromDate(new Date()));
        DayPlanMainInfoRes res = dayPlanService.getDayPlanListForIndexPage(req);
        return Result.ok(res);
    }

    /**
     * 某天的计划列表
     * 顺便返回当前积分卡的积分
     */
    @PostMapping(value = "oneDayPlanList")
    public Result<List<DayPlanListRes>> oneDayPlanList(@RequestBody DayPlanListReq req, HttpServletRequest httpRequest) {
        if (req.getTeamId() == null || req.getCardId() == null || req.getYearMonthDay() == null) {
            return Result.fail(BaseCode.PARAM_ERROR);
        }
        UserVO user = (UserVO) httpRequest.getAttribute(Constant.USER_KEY);
        if (!teamService.isUserInTeam(req.getTeamId(), user.getId())) {
            return Result.fail(BaseCode.ILLEGAL_OPERATION);
        }
        return Result.ok(dayPlanService.list(req));
    }

    /**
     * 一键完成
     */
    @PostMapping(value = "completeForIdList")
    public Result<String> completeForIdList(@RequestBody CompleteAllReq req, HttpServletRequest httpRequest) {
        if (req.getTeamId() == null || req.getCardId() == null || CollectionUtils.isEmpty(req.getIdList())) {
            return Result.fail(BaseCode.PARAM_ERROR);
        }
        UserVO user = (UserVO) httpRequest.getAttribute(Constant.USER_KEY);
        if (!teamService.isUserInTeam(req.getTeamId(), user.getId())) {
            return Result.fail(BaseCode.ILLEGAL_OPERATION);
        }
        if (req.getIdList().size() > 100) {
            return Result.fail(BaseCode.ILLEGAL_OPERATION);
        }
        return dayPlanService.completeForIdList(req, user);
    }

    /**
     * 复制某天的计划
     */
    @PostMapping(value = "copyHistory")
    public Result<String> copyOneDayPlanList(@RequestBody CopyHistoryDayPlanReq req, HttpServletRequest httpRequest) {
        if (req.getTeamId() == null || req.getCardId() == null || req.getYearMonthDay() == null) {
            return Result.fail(BaseCode.PARAM_ERROR);
        }
        if (req.getDays() == null) {
            // 默认只适用一天1天，最长5天
            req.setDays(1);
        } else {
            if (req.getDays() > 5) {
                Result.fail(BaseCode.PARAM_ERROR);
            }
        }
        UserVO user = (UserVO) httpRequest.getAttribute(Constant.USER_KEY);
        if (!teamService.isUserInTeam(req.getTeamId(), user.getId())) {
            return Result.fail(BaseCode.ILLEGAL_OPERATION);
        }
        return dayPlanService.copyoneDayPlanList(req, user);
    }

    private Result<Long> checkParam(DayPlanAddOrUpdateReq plan, UserVO vo) {
        if (plan.getName() == null || plan.getTeamId() == null || plan.getCardId() == null || plan.getAwardPoint() == null
            || plan.getYearMonthDay() == null) {
            return Result.fail(BaseCode.PARAM_ERROR);
        }
        if (plan.getName().length() > Constant.NAME_MAX_LENGTH) {
            return Result.fail(BaseCode.PARAM_ERROR);
        }
        if (!teamService.isUserInTeam(plan.getTeamId(), vo.getId())) {
            return Result.fail(BaseCode.ILLEGAL_OPERATION);
        }
        return Result.ok();
    }
}
